package cn.kgc.util;

import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.Arrays;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @author YC
 * Redis工具类
 */
@Component
public class RedisUtil {

    @Resource
    private RedisTemplate<String, Object> redisTemplate;

    private static final String LUA =
            "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";

    public boolean execute(String lockName, String uuid) {
        long result = redisTemplate.execute(
                new DefaultRedisScript<>(LUA, Long.class),
                Arrays.asList(lockName),
                uuid
        ).longValue();
        return result == 1;
    }

    /**
     * 获得key对应的值,并且值+1
     *
     * @param key
     * @return
     */
    public long increment(String key) {
        return redisTemplate.opsForValue().increment(key);
    }

    /**
     * 如果key不存在,在保存key和value。设置 key value的存活时间。
     *
     * @param key      键
     * @param value    值
     * @param times    保存在redis中的存活时间
     * @param timeUnit 时间单位
     * @return 是否保存成功 true保存成功   false保存失败
     */
    public boolean setIfAbsent(String key, Object value, long times, TimeUnit timeUnit) {
        return redisTemplate.opsForValue().setIfAbsent(key, value, times, timeUnit);
    }

    /**
     * 保存 key value
     *
     * @param key
     * @param value
     */
    public void set(String key, Object value) {
        redisTemplate.opsForValue().set(key, value);
    }

    /**
     * 保存key value  设置了存活时间
     *
     * @param key      键
     * @param value    值
     * @param times    存活时间
     * @param timeUnit 时间单位
     */
    public void set(String key, Object value, long times, TimeUnit timeUnit) {
        redisTemplate.opsForValue().set(key, value, times, timeUnit);
    }

    /**
     * 根据key获得对应的value
     *
     * @param key
     * @return value
     */
    public Object get(String key) {
        return redisTemplate.opsForValue().get(key);
    }

    /**
     * 根据key和fieldName获得对应的fieldValue的值
     *
     * @param key
     * @param filedName
     * @return fieldValue
     */
    public Object get(String key, Object filedName) {
        return redisTemplate.opsForHash().get(key, filedName);
    }

    /**
     * 判断key是否存在
     *
     * @param key 键
     * @return 是否存在 存在true 不存在false
     */
    public boolean hasKey(String key) {
        return redisTemplate.hasKey(key);
    }

    /**
     * 判断key中的fieldName是否存在
     *
     * @param key
     * @param filedName
     * @return
     */
    public boolean hasKey(String key, Object filedName) {
        return redisTemplate.opsForHash().hasKey(key, filedName);
    }

    /**
     * 保存key 对应的 fieldName 和 fieldValue
     *
     * @param key
     */
    public void putKey(String key, Object fieldName, Object fieldValue) {
        redisTemplate.opsForHash().put(key, fieldName, fieldValue);
    }

    /**
     * 获得key对应的所有的fieldName和fieldValue
     *
     * @param key
     * @return
     */
    public Map<Object, Object> getHash(String key) {
        return redisTemplate.opsForHash().entries(key);
    }

    /**
     * 删除key中对应的fieldName
     *
     * @param key
     * @param fieldName
     * @return
     */
    public boolean delete(String key, String fieldName) {
        return redisTemplate.opsForHash().delete(key, fieldName) > 0;
    }

    /**
     * 删除key
     *
     * @param key
     * @return
     */
    public boolean delete(String key) {
        return redisTemplate.delete(key);
    }

}